﻿/**
 *基本全局变量
 */
var IsAddClicked = false;
var mapClickHandler;
var mode = true;  //mode为true表示距离,false表示面积
//注意，测距与测面积不可同时进行
var isDistanceClick=false;
var isAreaClick=false;
/**
*以下对象维护一个marker的链表
*/
var head = new Object();//marker链表的头结点
var tail = new Object();//marker链表的尾结点
head.next = tail;//头结点的下一个结点
tail.prev = head;//尾结点的前一个结点
var last;

/**
 * 点击测距
 */
function DistanceClick()
{
    if(isAreaClick)  //如果正在测面积
         document.getElementById("Errortips").innerHTML = "提示信息 : 请先退出测面积模式，然后再切换到测距模式";
     else {
            isDistanceClick=!isDistanceClick;
            if(isDistanceClick)  //点击的时候
           {
                document.getElementById("btnDistance").innerHTML="取消";
				document.getElementById("btnDistance").style.fontWeight = 'bold';
				document.getElementById("DistanceInfo").style.display = 'block';
                document.getElementById("Errortips").innerHTML = "提示信息 : 进入测距模式，退出请点击取消";
                mode = true;
                mapClickHandler = GEvent.addListener(map,'click',onMapClicked);
           }
            else   {
                document.getElementById("btnDistance").innerHTML="测距";
				document.getElementById("btnDistance").style.fontWeight = 'normal';
				document.getElementById("DistanceInfo").style.display = 'none';
                document.getElementById("Errortips").innerHTML = "";
                document.getElementById("DistanceInfo").innerHTML = "距离:";
                reset();
                GEvent.removeListener(mapClickHandler);
            }
     }
}

/**
 * 点击测面积
 */
function AreaClick()
{
    if(isDistanceClick)  //如果正在测距
         document.getElementById("Errortips").innerHTML = "提示信息 : 请先退出测距模式，然后再切换到测面积模式";
     else  {
            isAreaClick =!isAreaClick;
            if(isAreaClick)  //点击的时候
             {
                document.getElementById("btnArea").innerHTML="取消";
				document.getElementById("btnArea").style.fontWeight = 'bold';
				document.getElementById("AreaInfo").style.display = 'block';
                document.getElementById("Errortips").innerHTML = "进入测面积模式，退出请点击取消";
                mode = false;
                mapClickHandler = GEvent.addListener(map,'click',onMapClicked);
             }
            else  {
                document.getElementById("btnArea").innerHTML="测面积";
				document.getElementById("btnArea").style.fontWeight = 'normal';
				document.getElementById("AreaInfo").style.display = 'none';
                document.getElementById("Errortips").innerHTML = "提示信息 : ";
                document.getElementById("AreaInfo").innerHTML = "面积:"
                reset();
                GEvent.removeListener(mapClickHandler);
            }
    }
}

/**
 * 用恰当的格式表示面积
 */
function formatArea(s) 
{  
  s = Math.round(s);
  if (s <= 1000000) {
    return s + ' ' + "平方米";
  } else if (s <= 1000000000000) {
    return s / 1000000 + ' ' + "平方公里";
  }
  return Math.round(s / 1000000) + ' ' + "平方公里";
}

/**
 * 用恰当的格式表示距离
 */
function formatDistance(len) 
{  
  len = Math.round(len);
  if (len <= 1000) {
    return len + ' ' + "米";
  } else if (len <= 1000000) {
    return len / 1000 + ' ' + "公里";
  }
  return Math.round(len / 1000) + ' ' + "公里";
}


/**
 * 事件处理函数：当用户选择删除标记时被调用，这里要删除与该标记连接的线段
 */
function removePoint(marker) {  
  // 先从地图上删除该标记
  map.removeOverlay(marker);
  // 对于中间结点，还要把它的前驱和后继用线段连接起来
  if (marker.prev.getLatLng && marker.next.getLatLng) {
    var segment = [marker.prev.getLatLng(), marker.next.getLatLng()];
    var polyline = new GPolyline(segment,"#666600",3);
    marker.prev.segNext = polyline;
    marker.next.segPrev = polyline;
    map.addOverlay(polyline);
  }
  marker.prev.next = marker.next;
  marker.next.prev = marker.prev;
  if (marker.segPrev)
   	map.removeOverlay(marker.segPrev);
  else if(!mode)
  {
		if(last)
			map.removeOverlay(last);
		last = new GPolyline([marker.next.getLatLng(),tail.prev.getLatLng()],"#666600",3);
		map.addOverlay(last);
  }
  
  if (marker.segNext)
    map.removeOverlay(marker.segNext);
  else if(!mode)
  {
		if(last)
			map.removeOverlay(last);
		last = new GPolyline([marker.prev.getLatLng(),head.next.getLatLng()],"#666600",3);
		map.addOverlay(last);
  }
    if(mode)
	      updateDistance();
	  else
	  	  updateArea();
}

function createInfoWindow(marker) 
{  
  // 为气泡提示窗口创建动态 DOM 对象，这里我们用 DIV 标签
  var div = document.createElement('div');
  div.style.fontSize = '10.5pt';
  div.style.width = '250px';
  div.appendChild(
    document.createTextNode(formatLatLng(marker.getLatLng())));
    
  var hr = document.createElement('hr');
  hr.style.border = 'solid 1px #cccccc';
  div.appendChild(hr);
  
  // 创建“删除”按钮
  var lnk = document.createElement('div');
  lnk.innerHTML = "删除此地标";
  lnk.style.color = '#0000cc';
  lnk.style.cursor = 'pointer';
  lnk.style.textDecoration = 'underline';
  
  // 为“删除”按钮添加事件处理：调用 removePoint() 并重新计算距离
  lnk.onclick =
    function() {
      map.closeInfoWindow();
      removePoint(marker);
	  if(mode)
	      updateDistance();
	  else
	  	  updateArea();
    };
  div.appendChild(lnk);
  
  // 当用户关闭信息窗口时 Google 地图 API 会自动释放该对象 
  return div;
}

/**
 * 事件处理函数：当用户单击地图时，要在该位置添加一个标记
 */
function onMapClicked(marker, latlng)
{
	// 如果用户单击的是标记，不再这里处理
	if(marker)
		return;
	
	// 创建标记，并添加到链表中
	var newMarker = new GMarker(latlng,{draggable:true});
	
	var pos = tail.prev;
	newMarker.prev = pos;
	newMarker.next = pos.next;
	pos.next.prev = newMarker;
	pos.next = newMarker;
	
	GEvent.addListener(newMarker,'dragend',function() 
	{
      	map.closeInfoWindow();
      	updateSegMents(newMarker);
		if(mode)
	      	updateDistance();
		else
			updateArea();
		
    })
	  // 为标记添加事件处理函数：单击标记时要显示信息窗口
  	GEvent.addListener(newMarker,'click',function() 
	{
	   snapShotControl.hide();
      	newMarker.openInfoWindowHtml(createMonitorPointInfoWindow(newMarker));//createInfoWindow(newMarker)
    }
	)
	
	  // 将创建的标记添加到地图中
	map.addOverlay(newMarker);
	
	if (newMarker.prev != head) {
		// 如果这不是第一个标记，则创建连接到上一个标记的线段，并显示在地图中
		var segment = [newMarker.prev.getLatLng(), latlng];
		newMarker.segPrev = new GPolyline(segment, "#666600",3);
		newMarker.prev.segNext = newMarker.segPrev;
		map.addOverlay(newMarker.segPrev);
		
		// 更新距离显示
		if(mode)
			updateDistance();
		else
		{
			updateArea();
			if(last)
				map.removeOverlay(last);
			last = new GPolyline([head.next.getLatLng(), newMarker.getLatLng()], "#666600",3);
			map.addOverlay(last);
		}
	}
}

/**
 * 事件处理函数：当用户拖拽标记、标记坐标改变时被调用，这里要更新与该标记连接的线段
 */
function updateSegMents(marker)
{
	var segment;
	// 更新连接前驱的线段
  	if (marker.segPrev && marker.prev.getLatLng)
	{
    	// 从地图上删除旧的线段
    	map.removeOverlay(marker.segPrev);
    
    	// 根据标记的当前坐标构造新的线段，并更新链表结点的相关字段
    	segment = [marker.prev.getLatLng(), marker.getLatLng()];
    	marker.segPrev = new GPolyline(segment,"#666600",3);
    	marker.prev.segNext = marker.segPrev;
    
    	// 将新线段添加到地图中
    	map.addOverlay(marker.segPrev);
  	}
	else if(!mode)
	{
		if(last)
			map.removeOverlay(last);
		last = new GPolyline([tail.prev.getLatLng(),marker.getLatLng()],"#666600",3);
		map.addOverlay(last);
	}
	
	// 更新连接后继的线段，与上类似
  	if (marker.segNext && marker.next.getLatLng())
	{
	    map.removeOverlay(marker.segNext);
	    segment = [marker.getLatLng(), marker.next.getLatLng()];
	    marker.segNext = new GPolyline(segment,"#666600",3);
	    marker.next.segPrev = marker.segNext;
	    map.addOverlay(marker.segNext);
  	}
	else if(!mode)
	{
		if(last)
			map.removeOverlay(last);
		last = new GPolyline([head.next.getLatLng(),marker.getLatLng()],"#666600",3);
		map.addOverlay(last);
	}
}

/**
 * 统计总面积，并显示在网页中
 */
function updateArea()
{
	var s = getArea();
	document.getElementById("AreaInfo").innerHTML = "面积:"+formatArea(s);
}

/**
 * 统计总距离，并显示在网页中
 */
function updateDistance() 
{
  var len = getDistance();
  document.getElementById("DistanceInfo").innerHTML = "距离: "+formatDistance(len);
}

/**
 * 遍历链表，统计总面积
 */
function getArea()
{
  var s = 0;
  var t;
  var a;
  var b;
  var c;
  
  if(head.next&&head.next.next&&head.next.next.next)
  {
  	for (var m = head.next.next; m != tail.prev; m = m.next) {
		a = head.next.getLatLng().distanceFrom(m.getLatLng());
		b = head.next.getLatLng().distanceFrom(m.next.getLatLng());
		c = m.getLatLng().distanceFrom(m.next.getLatLng());
		t = (a + b + c) / 2.0;
		s += Math.sqrt(t * (t - a) * (t - b) * (t - c));
	}
  }
  return s;
}

/**
 * 遍历链表，统计总距离
 */
function getDistance()
{
  var len = 0;
  
  // 周游链表，累计相邻两个标记间的距离
  for (var m = head; m != tail; m = m.next) {
    if (m.prev && m.prev.getLatLng)
      len += m.prev.getLatLng().distanceFrom(m.getLatLng());
  }
  return len;
}

function reset() {  
  for (var m = head.next; m != tail; m = m.next) {
    map.removeOverlay(m);
    if (m.segNext)
      map.removeOverlay(m.segNext);
  }
 if(!mode)
     map.removeOverlay(last);
  head = new Object();
  tail = new Object();
  head.next = tail;
  tail.prev = head;
  
  if(mode)
  	updateArea();  	
  else
	updateDistance();
}

function formatLatLng(pt) 
{  
  var latName, lngName;
  var lat = pt.lat();
  var lng = pt.lng();
  latName = lat >= 0 ? '北纬' : '南纬';
  lngName = lng >= 0 ? '东经' : '西经';

  return lngName + formatDegree(lng) + '，' 
    + latName + formatDegree(lat);
}

/**
 * 格式化角度为字符串
 */
function formatDegree(value)
{
  value = Math.abs(value);
  var v1 = Math.floor(value);
  var v2 = Math.floor((value - v1) * 60);
  var v3 = Math.round((value - v1) * 3600 % 60);
  return v1 + '°' + v2 + '\'' + v3 + '"';
}